extends Node2D
class_name MoveManager

var _cells_can_move: Array[Vector2i]
var _path: Array[Vector2i]

var terrain_cost_map: Dictionary = {
									   "Grass": 1, "GrassRightSlope": 2, "GrassLeftSlope": 2, "GrassUpSlope": 2, "GrassDownSlope": 2,
									   "Stone": 2, "StoneLeftSlope": 4, "StoneUpSlope": 4, "StoneDownSlope": 4, "StoneRightSlope": 4,
									   "Ground": 1, "GroundLeftSlope": 2, "GroundUpSlope": 2, "GroundDownSlope": 2, "GroundRightSlope": 2,
									   "Sea": 2
								   }

@export var third_high_ground_layer: TileMapLayer
@export var high_light_layer: TileMapLayer

var astar = AStar2D.new()
var move_hight_light_cell:Vector2i = Vector2i(1, 0)
var path_hight_light_cell:Vector2i = Vector2i(4, 0)
var move_target_cell:Vector2i

	
#region 移动
func move_character_to(chosen_unit: Player) -> void:
	if not chosen_unit:
		push_error("请选择一个角色")
		return
	if not can_move(move_target_cell):
		_move_complete()
		return
	if not _cells_can_move or _cells_can_move.is_empty():
		return
	if not _cells_can_move.has(move_target_cell):
		_move_complete()
		return
	if _path.size() > 1:
		await _move_along_path(chosen_unit, _path)
		chosen_unit.cur_cell = move_target_cell
		_move_complete()


func _move_complete() -> void:
	clear_move_preview()
	_clear_path_preview(_path)
	_path = []
	print("moveManager 修改状态为BASE")
	astar.clear()


func _move_along_path(unit: Node2D, path: Array[Vector2i]):
	# 假设你的角色是 node2d 类型
	var tween: Tween = get_tree().create_tween()
	for point in path:
		var world_pos: Vector2  = TileMapUtil.convert_layer_coordinate_2_globle_p(point, third_high_ground_layer)
		var tile_data: TileData = third_high_ground_layer.get_cell_tile_data(point)
		tween.tween_property(unit, "position", world_pos, 0.2) # 0.5秒移动到下一个格
	await tween.finished
#endregion 移动

#region 视图处理
func show_path_preview(target_cell:Vector2i, start_cell: Vector2i) -> void:
	if not _cells_can_move.has(target_cell):
		print_debug("目标格子不可行," , target_cell)
		return

	var new_path: Array[Vector2i] = _a_star_pathfinding(start_cell, target_cell)
	_replace_path_preview(ArrayUtils.find_difference(_path, new_path))
	_highlight_path(ArrayUtils.find_difference(new_path, _path))
	_path = new_path

func show_move_preview(chosen_unit: Player) -> void:
	if not chosen_unit:
		push_error("请选择一个角色")
		return

	var start_cell: Vector2i            = TileMapUtil.convert_globle_p_2_layer_cell(chosen_unit.position, third_high_ground_layer)
	var cells_can_move: Array[Vector2i] = _calculate_move_range(start_cell, chosen_unit.move_range)
	if not cells_can_move and cells_can_move.is_empty():
		return
	cells_can_move.append(start_cell)
	_cells_can_move = cells_can_move
	_build_astar(_cells_can_move)  # 构建A*图
	_high_light_can_move_cells()  # 显示移动路径预览

func _high_light_can_move_cells() -> void:
	if _cells_can_move.is_empty():
		return
	for cell in _cells_can_move:
		high_light_layer.set_cell(cell, 1, move_hight_light_cell)


func clear_move_preview() -> void:
	if _cells_can_move.is_empty():
		return

	for cell in _cells_can_move:
		high_light_layer.erase_cell(cell)

func _highlight_path(path: Array[Vector2i]) -> void:
	if path.is_empty():
		return
	for cell in path:
		high_light_layer.set_cell(cell, 1, path_hight_light_cell)


func _replace_path_preview(path: Array[Vector2i]) -> void:
	if path.is_empty():
		return
	for cell in path:
		high_light_layer.erase_cell(cell)
		high_light_layer.set_cell(cell, 1, move_hight_light_cell)


func _clear_path_preview(path: Array[Vector2i]) -> void:
	if path.is_empty():
		return
	for cell in path:
		high_light_layer.erase_cell(cell)

#endregion 视图处理

#region 逻辑判断

func can_move(target_cell:Vector2i)-> bool:
	if not _cells_can_move or _cells_can_move.is_empty():
		print_debug("没有格子可以移动")
		return false
	if not _cells_can_move.has(target_cell):
		return false
	var heros:Array[Node] = get_tree().get_nodes_in_group("unit")
	for hero:Player in heros:
		if hero and hero.cur_cell == target_cell:
			print("目标格子已有角色")
			return false
	return true
#endregion 逻辑判断

#region 寻路算法逻辑
func _get_astar_id(cell: Vector2i) -> int:
	return (cell.x + 1000) * 2000 + (cell.y + 1000)

func _build_astar(walkable_cells: Array[Vector2i]):
	astar.clear()
	for cell in walkable_cells:
		var id: int = _get_astar_id(cell)
		astar.add_point(id, Vector2(cell.x, cell.y))
	# 连边
	for cell in walkable_cells:
		var id: int = _get_astar_id(cell)
		for neighbor in _get_neighbors(cell):
			if walkable_cells.has(neighbor):
				var neighbor_id: int = _get_astar_id(neighbor)
				# 检查是否可以通行（考虑跳跃能力和高度差）
				if not astar.are_points_connected(id, neighbor_id):
					astar.connect_points(id, neighbor_id)

# 获取格子高度
func _get_cell_height(cell: Vector2i) -> int:
	var tile_data: TileData = third_high_ground_layer.get_cell_tile_data(cell)
	if tile_data:
		return tile_data.get_custom_data("height")
	return 0

func _get_neighbors(cell: Vector2i) -> Array:
	var dirs: Array[Variant]   = [Vector2i.LEFT, Vector2i.RIGHT, Vector2i.UP, Vector2i.DOWN] # 四方向
	var result: Array[Variant] = []
	for dir in dirs:
		var neighbor = cell + dir
		result.append(neighbor)
	return result

func _calculate_move_range(start_cell: Vector2i, max_steps: int) -> Array[Vector2i]:
	var visited: Array[Vector2i]   = []
	var queue: Array[Variant]      = [{"cell": start_cell, "cost": 0}]
	var directions: Array[Variant] = [Vector2i.LEFT, Vector2i.RIGHT, Vector2i.UP, Vector2i.DOWN]

	while queue:
		var current = queue.pop_front()
		if current.cost >= max_steps or current.cell in visited:
			continue
		visited.append(current.cell)

		# 获取地形类型（假设通过自定义数据层实现）
		var terrain_type: String = _get_terrain_type(current.cell)
		var base_cost: int       = terrain_cost_map.get(terrain_type, 999)
		if base_cost == 999: # 不可通行地形
			continue

		for dir in directions:
			var next_cell = current.cell + dir
			# 检查是否可以通行（考虑跳跃能力和高度差）
			#if _can_traverse(current.cell, next_cell):
			var next_cost: int = _get_next_cost(base_cost, next_cell)
			if next_cost + current.cost <= max_steps:
				#if _is_cell_passable(next_cell):  # 检查障碍物
				queue.append({"cell": next_cell, "cost": current.cost + base_cost})
	return visited.filter(func(cell): return cell != start_cell) as Array[Vector2i]


# 从 TileMapLayer 获取地形类型（需在 TileSet 中配置自定义数据层）
func _get_terrain_type(cell: Vector2i) -> String:
	var tile_data: TileData = third_high_ground_layer.get_cell_tile_data(cell)
	if tile_data:
		var tile_type = tile_data.get_custom_data("type")
		if not tile_type:
			push_error("未设置tile类型")
		return tile_type
	else:
		push_error("获取tile数据失败")
	return "null"
	
func _get_next_cost(cur_cost: int, cell: Vector2i) -> int:
	var tile_data: TileData = third_high_ground_layer.get_cell_tile_data(cell)
	if tile_data:
		var type      = tile_data.get_custom_data("type")
		var base_cost = terrain_cost_map.get(type, 999)
		# 考虑高度差对移动消耗的影响
		return base_cost + cur_cost
	return 999

#a_star_pathfinding 考虑地形阻力寻找移动路径
func _a_star_pathfinding(start: Vector2i, goal: Vector2i) -> Array[Vector2i]:
	# 使用Godot内置的AStar2D类
	var path_ids: PackedInt64Array = astar.get_id_path(_get_astar_id(start), _get_astar_id(goal))
	var path: Array[Vector2i]      = []
	for id in path_ids:
		var point: Vector2 = astar.get_point_position(id)
		path.append(Vector2i(point))
	return path
#endregion 寻路算法逻辑
